#include "Simulator.h"
#define MAX_CHARS 256

Simulator::Simulator():m_grid(1024,1024,1024,0){
  m_surfDisplay = NULL;
  ParseVRML();
  //m_grid.SetLine(0,0,3,256,256,3,12);
  onExecute();
}

//Temporary -----------------------------------------------
void Simulator::ParseVRML(){
  double minx = 10000,miny = 10000,minz = 10000;
  double maxx =-10000,maxy =-10000,maxz =-10000;
  double sc = 2.5;
  std::ifstream vrmlfile;
  vrmlfile.open("newcol.bt.wrl");
  if(vrmlfile.is_open()){
    char cur_line[MAX_CHARS];
    while(!vrmlfile.eof()){
      vrmlfile.getline(cur_line,MAX_CHARS);
      char *cur_tok = strtok(cur_line, " \t\r\n");
      if(strlen(cur_line) && !strcmp(cur_tok,"Transform")){
	double x = sc*(atof(strtok(NULL, " {translation"))+13.5);//Remove!
	double y = sc*(atof(strtok(NULL, " "))+22.7);
	double z = sc*(atof(strtok(NULL, " "))-7.9);
	m_grid.Set(x,y,z,12);
	minx = minx>x ? x:minx;
	miny = miny>y ? y:miny;
	minz = minz>z ? z:minz;
	maxx = maxx<x ? x:maxx;
	maxy = maxy<y ? y:maxy;
	maxz = maxz<z ? z:maxz;
	
      }
    }
    std::cout << "minsNmaxs: " << minx << "," << maxx << ","
	      << miny << "," << maxy << "," << minz << "," << maxz << "\n";
  }
  vrmlfile.close();
}

void Simulator::ParseText(){
  double minx = 10000,miny = 10000,minz = 10000;
  double maxx =-10000,maxy =-10000,maxz =-10000;
  double sc = 15.0;
  std::ifstream txtfile;
  txtfile.open("NewCollegeMap_short.txt");
  if(txtfile.is_open()){
    char cur_line[MAX_CHARS];
    txtfile.getline(cur_line,MAX_CHARS);
    while(!txtfile.eof()){
      txtfile.getline(cur_line,MAX_CHARS);
      if(strlen(cur_line)){
	double x = sc*(atof(strtok(cur_line, " ,"))-0.8);
	double y = sc*(atof(strtok(NULL, " ,"))-19.0);
	double z = sc*(atof(strtok(NULL, " ,"))+0.3);
	m_grid.Set(x,y,z,12);
	minx = minx>x ? x:minx;
	miny = miny>y ? y:miny;
	minz = minz>z ? z:minz;
	maxx = maxx<x ? x:maxx;
	maxy = maxy<y ? y:maxy;
	maxz = maxz<z ? z:maxz;
	
      }
    }
    std::cout << "minsNmaxs: " << minx << "," << maxx << ","
	      << miny << "," << maxy << "," << minz << "," << maxz << "\n";
  }
  txtfile.close();
}

int Simulator::onExecute(){
  if(onInit() == false) {
    return -1;
  }
  while(EventHandler::isRunning()){
    EventHandler::pollEvents();
    onLoop();
    onRender();
  }
  onCleanup();
  return 0;
}

bool Simulator::onInit(){
  if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
    return false;
  }
  EventHandler::init();
  if((m_surfDisplay = SDL_SetVideoMode(640, 480, 32, 
      SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL)) == NULL) {
    return false;
  }
  glClearColor(0, 0, 0, 0);
  glClearDepth(1.0f);
  
  glViewport(0, 0, 640, 480);//Fix this ------------------
  
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  
  glFrustum(-2,2,-2,2,2,100);
  glMatrixMode(GL_MODELVIEW);
  
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
  GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

  glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  glLightfv(GL_LIGHT0, GL_POSITION, light_position);

  glLoadIdentity();
  m_camX = 0; m_camY = 0; m_camZ = 0; m_camAz = 0; m_camEl = 0;
  return true;
}

void Simulator::onLoop(){
  double spd = 3.0;
  if(EventHandler::getState(EH_O,EH_CUR)){m_camZ-=spd;}
  if(EventHandler::getState(EH_P,EH_CUR)){m_camZ+=spd;}
  if(EventHandler::getState(EH_UP,EH_CUR)){m_camY-=spd;}
  if(EventHandler::getState(EH_DOWN,EH_CUR)){m_camY+=spd;}
  if(EventHandler::getState(EH_LEFT,EH_CUR)){m_camX+=spd;}
  if(EventHandler::getState(EH_RIGHT,EH_CUR)){m_camX-=spd;}
  if(EventHandler::getState(EH_A,EH_CUR)){m_camAz-=spd;}
  if(EventHandler::getState(EH_D,EH_CUR)){m_camAz+=spd;}
  if(EventHandler::getState(EH_W,EH_CUR)){m_camEl-=spd;}
  if(EventHandler::getState(EH_S,EH_CUR)){m_camEl+=spd;}
  
}

void Simulator::onRender(){
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  glRotatef(m_camEl, 1, 0, 0);
  glRotatef(m_camAz, 0, 1, 0);
  glRotatef(-90, 1, 0, 0);
  glTranslatef(m_camX,m_camY,m_camZ);
  
  m_grid.Draw();
  
  SDL_GL_SwapBuffers();
}

void Simulator::onCleanup(){
  SDL_Quit();
}

